package top.mydb.hejianwei.tm;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import top.mydb.hejianwei.common.Error;
import top.mydb.hejianwei.utils.Panic;
public interface  TransactionManager {
    String XID_FILE_SUFFIX = ".xid";
    long begin();
    void commit(long xid);
    void abort(long xid);
    boolean isActive(long xid);
    boolean isCommitted(long xid);
    boolean isAborted(long xid);
    void close();

    // [REVISED] The create method now properly initializes the file and delegates to open().
    public static TransactionManager create(String path) {
        File f = new File(path + TransactionManagerImpl.XID_FILE_SUFFIX);
        try {
            if (!f.createNewFile()) {
                Panic.panic(Error.FileExistsException);
            }
        } catch (Exception e) {
            Panic.panic(e);
        }
        if (!f.canRead() || !f.canWrite()) {
            Panic.panic(Error.FileNotReadableException);
        }

        // Initialize the file header.
        // Use try-with-resources to ensure file handles are closed immediately after initialization.
        try (RandomAccessFile raf = new RandomAccessFile(f, "rw");
             FileChannel fc = raf.getChannel()) {
            ByteBuffer buf = ByteBuffer.wrap(new byte[TransactionManagerImpl.LEN_XID_HEADER_LENGTH]);
            fc.position(0);
            fc.write(buf);
        } catch (IOException e) {
            Panic.panic(e);
        }

        // Let the open method create the actual TransactionManager instance.
        return open(path);
    }

    // [REVISED] The open method now simply creates an instance of TransactionManagerImpl.
    public static TransactionManager open(String path) {
        File f = new File(path + TransactionManagerImpl.XID_FILE_SUFFIX);
        if (!f.exists()) {
            Panic.panic(Error.FileNotExistsException);
        }
        if (!f.canRead() || !f.canWrite()) {
            Panic.panic(Error.FileNotReadableException);
        }

        // The implementation is now responsible for its own file management.
        return new TransactionManagerImpl(path);
    }
}